extends layout

append style
  link(rel="stylesheet", href="/docs/css/inlinecpc.css")
  script(type="text/javascript" src="/docs/js/native.js")

block content
  :markdown
    ## Documents

    <script>
      _native.init("CK7DT53U",{
        targetClass: 'native-inline'
      });
    </script>

    <div class="native-inline">
      <a href="#native_link#"><span class="sponsor">Sponsor</span> #native_company# — #native_desc#</a>
    </div>

    Mongoose [documents](./api.html#document-js) represent a one-to-one mapping
    to documents as stored in MongoDB. Each document is an instance of its
    [Model](./models.html).

    <ul class="toc">
      <li><a href="#documents-vs-models">Documents vs Models</a></li>
      <li><a href="#retrieving">Retrieving</a></li>
      <li><a href="#updating">Updating</a></li>
      <li><a href="#validating">Validating</a></li>
      <li><a href="#overwriting">Overwriting</a></li>
    </ul>

    ### Documents vs Models

    [Document](api.html#Document) and [Model](api.html#Model) are distinct
    classes in Mongoose. The Model class is a subclass of the Document class.
    When you use the [Model constructor](api.html#Model), you create a
    new document.

    ```javascript
    const MyModel = mongoose.model('Test', new Schema({ name: String }));
    const doc = new MyModel();

    doc instanceof MyModel; // true
    doc instanceof mongoose.Model; // true
    doc instanceof mongoose.Document; // true
    ```

    In Mongoose, a "document" generally means an instance of a model.
    You should not have to create an instance of the Document class without
    going through a model.

    ### Retrieving

    When you load documents from MongoDB using model functions like [`findOne()`](api.html#model_Model.findOne),
    you get a Mongoose document back.

    ```javascript
    const doc = await MyModel.findOne();

    doc instanceof MyModel; // true
    doc instanceof mongoose.Model; // true
    doc instanceof mongoose.Document; // true
    ```

    ### Updating

    Mongoose documents track changes. You can modify a document using vanilla
    JavaScript assignments and Mongoose will convert it into [MongoDB update operators](https://docs.mongodb.com/manual/reference/operator/update/).

    ```javascript
    doc.name = 'foo';

    // Mongoose sends a `updateOne({ _id: doc._id }, { $set: { name: 'foo' } })`
    // to MongoDB.
    await doc.save();
    ```

    If the document with the corresponding `_id` is not found, Mongoose will
    report a `DocumentNotFoundError`:

    ```javascript
    const doc = await MyModel.findOne();

    // Delete the document so Mongoose won't be able to save changes
    await MyModel.deleteOne({ _id: doc._id });

    doc.name = 'foo';
    await doc.save(); // Throws DocumentNotFoundError
    ```

    The [`save()`](api.html#model_Model-save) function is generally the right
    way to update a document with Mongoose. With `save()`, you get full
    [validation](validation.html) and [middleware](middleware.html).

    For cases when `save()` isn't flexible enough, Mongoose lets you create
    your own [MongoDB updates](https://docs.mongodb.com/manual/reference/operator/update/)
    with casting, [middleware](middleware.html#notes), and [limited validation](validation.html#update-validators).

    ```javascript
    // Update all documents in the `mymodels` collection
    await MyModel.updateMany({}, { $set: { name: 'foo' } });
    ```

    _Note that `update()`, `updateMany()`, `findOneAndUpdate()`, etc. do *not*
    execute `save()` middleware. If you need save middleware and full validation,
    first query for the document and then `save()` it._

    ### Validating

    Documents are casted validated before they are saved. Mongoose first casts
    values to the specified type and then validates them. Internally, Mongoose
    calls the document's [`validate()` method](api.html#document_Document-validate)
    before saving.

    ```javascript
    const schema = new Schema({ name: String, age: { type: Number, min: 0 } });
    const Person = mongoose.model('Person', schema);

    let p = new Person({ name: 'foo', age: 'bar' });
    // Cast to Number failed for value "bar" at path "age"
    await p.validate();

    let p2 = new Person({ name: 'foo', age: -1 });
    // Path `age` (-1) is less than minimum allowed value (0).
    await p2.validate();
    ```

    Mongoose also supports limited validation on updates using the [`runValidators` option](validation.html#update-validators).
    Mongoose casts parameters to query functions like `findOne()`, `updateOne()`
    by default. However, Mongoose does _not_ run validation on query function
    parameters by default. You need to set `runValidators: true` for Mongoose
    to validate.

    ```javascript
    // Cast to number failed for value "bar" at path "age"
    await Person.updateOne({}, { age: 'bar' });

    // Path `age` (-1) is less than minimum allowed value (0).
    await Person.updateOne({}, { age: -1 }, { runValidators: true });
    ```

    Read the [validation](./validation.html) guide for more details.

    ### Overwriting

    There are 2 different ways to overwrite a document (replacing all keys in the
    document). One way is to use the
    [`Document#overwrite()` function](/docs/api/document.html#document_Document-overwrite)
    followed by `save()`.

    ```javascript
    const doc = await Person.findOne({ _id });

    // Sets `name` and unsets all other properties
    doc.overwrite({ name: 'Jean-Luc Picard' });
    await doc.save();
    ```

    The other way is to use [`Model.replaceOne()`](/docs/api/model.html#model_Model.replaceOne).

    ```javascript
    // Sets `name` and unsets all other properties
    await Person.replaceOne({ _id }, { name: 'Jean-Luc Picard' });
    ```

    ### Next Up

    Now that we've covered Documents, let's take a look at
    [Subdocuments](/docs/subdocs.html).
